﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using Rung.EBook.DocFormater.Umd;
using Rung.EBook.Common.Model;
using Rung.EBook.UI.Forms;
using Rung.Common;

namespace Rung.EBook.UI.Controls.Panels
{
    public partial class pnTextAnalizer : UserControl
    {
        private WriteInfo mWriteInfo;
        private AppendInfo mAppendInfo;
        internal TextAnalizer currentTA;

        public pnTextAnalizer()
        {
            InitializeComponent();
            //this.FillRuleByType(RuleType.城北黑帮);
            //this.FillRuleByType(RuleType.黑道风云);
            //this.FillRuleByType(RuleType.三十八军在朝鲜);
            this.FillRuleByType(RuleType.狼群);
        }

        internal pnTextAnalizer(WriteInfo infoWriter, AppendInfo appendInfo)
            : this()
        {
            this.mWriteInfo = infoWriter;
            this.mAppendInfo = appendInfo;
        }

        private void pnTextAnalizer_Load(object sender, EventArgs e)
        {
            this.Dock = DockStyle.Fill;

            ConfigForm.LoadAnalizers();
            // 刷新菜单UI
            this.tsm载入已存方案_Refresh();
        }

        private void btnAnalizer_Click(object sender, EventArgs e)
        {
            // 初始化
            this.Analizer_FromUI();
            lbChapters.Items.Clear();

            currentTA.Analize();
            // 填充【章节列表】
            lbChapters.Items.AddRange(currentTA.Chapters.ConvertAll<string>(new Converter<TextAnalizer.ChapterInfo, string>((chapter) => { return chapter.Title; })).ToArray());
        }

        // 【启用章节拆分】
        private void cbChapterCutEnable_CheckedChanged(object sender, EventArgs e)
        {
            groupBoxChapterCut.Enabled = cbChapterCutEnable.Checked;
        }

        // 【启用无视行】
        private void cbIgnalLineEnable_CheckedChanged(object sender, EventArgs e)
        {
            groupBoxIgnalLine.Enabled = cbIgnalLineEnable.Checked;
        }

        // 【章节列表】选中章节
        private void lbChapters_SelectedIndexChanged(object sender, EventArgs e)
        {
            txbContent.Text = currentTA.Chapters[lbChapters.SelectedIndex].Content;
        }

        // 【转到电子书制作】
        private void btnTurnToBookMaker_Click(object sender, EventArgs e)
        {
            UmdBookBM bookBM = new UmdBookBM();

            foreach (var c in currentTA.Chapters)
            {
                ChapterBM cBM = new ChapterBM
                {
                    Index = this.lbChapters.Items.Count - 1,
                    Title = c.Title,
                    Content = c.Content
                };

                bookBM.AppendChapter(cBM);
            }

            TabControl tab = (this.ParentForm as Rung.EBook.UI.Forms.MainForm).tcMain;
            pnEBookMaker pn = tab.TabPages[2].Controls[0] as pnEBookMaker;
            pn.LoadBookBM(bookBM);
            tab.SelectedIndex = 2;
        }

        // 【设置】
        private void btnOption_Click(object sender, EventArgs e)
        {
            menuOption.Show(Control.MousePosition);
        }

        #region TextAnalizer 类
        [Serializable]
        internal class TextAnalizer
        {
            /// <summary>
            /// 规则名称（用于持久化）
            /// </summary>
            public string Name;
            /// <summary>
            /// 启用章节拆分
            /// </summary>
            internal bool ChapterCutEnable;
            /// <summary>
            /// 章节拆分规则
            /// </summary>
            internal List<string> ChapterCutRule;
            /// <summary>
            /// 无视行
            /// </summary>
            internal bool IgnalLineEnable;
            /// <summary>
            /// 对“无视行”规则进行正则表达式分析
            /// </summary>
            internal bool IgnalLineRegxModeEnable;
            /// <summary>
            /// 无视行规则
            /// </summary>
            internal List<string> IgnalLines;
            /// <summary>
            /// 启用意外换行恢复
            /// </summary>
            internal bool AccidentLineEnable;
            /// <summary>
            /// 启用空格清理
            /// </summary>
            internal bool WhiteSpaceEnable;
            /// <summary>
            /// 原文
            /// </summary>
            internal string PlainText;
            /// <summary>
            /// 分析结果
            /// </summary>
            [NonSerialized]
            internal List<ChapterInfo> Chapters;

            internal TextAnalizer()
            {
                this.IgnalLines = new List<string>();
                this.Chapters = new List<ChapterInfo>();
            }

            internal void Analize()
            {
                this.Chapters = new List<ChapterInfo>();
                string[] lines = this.PlainText.Split(new string[] { "\r\n", "\n\n" }, StringSplitOptions.RemoveEmptyEntries);

                string paragraph = null;// 当前段落（原小说中的完整段落。txt书籍中可能会将原文的段落强行换行）
                string linePre = "\t\t";
                string lineEnd = "\r\n";

                foreach (var line in lines)
                {
                    string l = line;// 分析器分析的当前行（txt文本中的一行，原小说的一段可能会被 txt 分成若干行）

                    // 无视行
                    if (this.IgnalLineEnable)
                    {
                        if (this.IgnalLineRegxModeEnable)// 以【正则模式】过滤无视内容
                        {
                            foreach (var rule in this.IgnalLines)
                            {
                                Regex regexI = new Regex(rule, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline | RegexOptions.Compiled);

                                //if (regexI.Match(line).Success)
                                //    continue;
                                l = regexI.Replace(l, "");
                            }
                        }
                        else// 以【非正则模式】过滤无视内容
                        {
                            if (this.IgnalLines.Contains(l.Trim()))
                                continue;
                    }
                    }

                    // 空格清理
                    paragraph += l.Trim();
                    if (string.IsNullOrEmpty(paragraph)) continue;

                    // 章节拆分
                    if (this.ChapterCutEnable)
                    {
                        bool isMatched = false;
                        foreach (var rule in this.ChapterCutRule)
                        {
                            Regex regexC = new Regex(rule, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Multiline | RegexOptions.Compiled);

                            if (regexC.Match(l).Success)
                            {
                                isMatched = true;

                                ChapterInfo chapter = new ChapterInfo();
                                chapter.Title = paragraph;
                                this.Chapters.Add(chapter);

                                paragraph = null;
                                continue;
                            }
                        }
                        if (isMatched) continue;
                    }

                    // 行清理（恢复意外换行）
                    bool needLineClean = false;
                    if (this.AccidentLineEnable)
                    {
                        if (this.IsEndWithPunctuation(paragraph))
                        {
                            needLineClean = true;
                            lineEnd = "\r\n";
                        }
                        else
                        {
                            lineEnd = string.Empty;
                            continue;
                        }
                    }
                    else
                    {
                        linePre = "\t\t";
                        lineEnd = "\r\n";
                        needLineClean = true;
                    }
                    this.Chapters[this.Chapters.Count - 1].Content += string.Format("{0}{1}{2}", linePre, paragraph, lineEnd);
                    if (needLineClean) paragraph = null;
                }
            }

            // 行清理
            private bool IsEndWithPunctuation(string l)
            {
                //char c = l[l.Length - 1];
                //return VAR_标点符号.Contains(c);
                foreach (var c in VAR_标点符号)
                {
                    if (l.EndsWith(c)) return true;
                }
                return false;
            }

            [NonSerialized]
            private readonly string[] VAR_标点符号 = new string[] { ".", "。", "”", "”", "\"", "！", "!", "？", "?", "：", ":", "…", "）", ")", "～", "~", "\">" };

            internal class ChapterInfo
            {
                internal string Title;
                internal string Content;

                internal ChapterInfo Clone()
                {
                    return new ChapterInfo
                    {
                        Title = this.Title,
                        Content = this.Content
                    };
                }
            }

            internal TextAnalizer Clone()
            {
                TextAnalizer a = new TextAnalizer
                {
                    AccidentLineEnable = this.AccidentLineEnable,
                    Chapters = new List<ChapterInfo>(),
                    ChapterCutEnable = this.ChapterCutEnable,
                    ChapterCutRule = this.ChapterCutRule,
                    IgnalLineEnable = this.IgnalLineEnable,
                    IgnalLineRegxModeEnable = this.IgnalLineRegxModeEnable,
                    IgnalLines = this.IgnalLines,
                    Name = this.Name,
                    PlainText = this.PlainText,
                    //VAR_标点符号 = this.VAR_标点符号,
                    WhiteSpaceEnable = this.WhiteSpaceEnable
                };

                foreach (var c in this.Chapters)
                {
                    a.Chapters.Add(c.Clone());
                }

                return a;
            }
        } 
        #endregion

        private void 载入规则ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.tsm载入已存方案_Refresh();
        }

        private void 保存规则ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Analizer_FromUI();
            new ConfigForm(this).Show(this);

            //string file = Rung.EBook.Common.Driver.StaticFunctions.GetRuleFileFullName();
            //Rung.Common.SerializeHelper.Serialize(this.analizers, file);
        }

        private void 清空规则ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfigForm.Analizers.Clear();
            SerializeHelper.Serialize(ConfigForm.Analizers, Rung.EBook.Common.Driver.StaticFunctions.GetTextAnalizerRulesFilePath());

            // 刷新菜单UI
            this.tsm载入已存方案_Refresh();
        }

        internal void tsm载入已存方案_Refresh()
        {
            载入规则ToolStripMenuItem.DropDownItems.Clear();
            //if (ConfigForm.Analizers == null || ConfigForm.Analizers.Count == 0) return;

            foreach (var a in ConfigForm.Analizers.Values)
            {
                ToolStripMenuItem bmItem = new ToolStripMenuItem(a.Name, null, (s, e) =>
                {
                    ToolStripMenuItem item = s as ToolStripMenuItem;
                    if (item != null)
                    {
                        this.currentTA = ConfigForm.Analizers[item.Text];// 设置为当前的工作
                        this.Analizer_ToUI(ConfigForm.Analizers[item.Text]);// 反映到 UI 上
                    }
                });

                bmItem.DropDownItems.Add("覆盖", null, (s, e) =>
                {
                    ToolStripMenuItem currentItem = s as ToolStripMenuItem;
                    if (currentItem != null)
                    {
                        TextAnalizer currentA = currentItem.OwnerItem.Tag as TextAnalizer;
                        if (currentA != null)
                        {
                            Analizer_FromUI();
                            ConfigForm.Analizers[currentA.Name] = this.currentTA;
                            SerializeHelper.Serialize(ConfigForm.Analizers, Rung.EBook.Common.Driver.StaticFunctions.GetTextAnalizerRulesFilePath());
                            MessageBox.Show("覆盖成功。");
                            tsm载入已存方案_Refresh();
                        }
                    }
                });

                bmItem.DropDownItems.Add("删除", null, (s, e) =>
                {
                    ToolStripMenuItem delItem = s as ToolStripMenuItem;
                    if (delItem != null)
                    {
                        TextAnalizer delA = delItem.OwnerItem.Tag as TextAnalizer;
                        if (delA != null)
                        {
                            ConfigForm.Analizers.Remove(delA.Name);
                            SerializeHelper.Serialize(ConfigForm.Analizers, Rung.EBook.Common.Driver.StaticFunctions.GetTextAnalizerRulesFilePath());
                            MessageBox.Show("删除成功。");
                            tsm载入已存方案_Refresh();
                        }
                    }
                });

                bmItem.Tag = a;
                // 刷新菜单UI
                载入规则ToolStripMenuItem.DropDownItems.Add(bmItem);
            }
        }

        private void Analizer_ToUI(TextAnalizer a)
        {
            cbChapterCutEnable.Checked = a.ChapterCutEnable;
            if (a.ChapterCutRule != null && a.ChapterCutRule.Count > 0)
                txbChapterCutRule.Text = string.Join("\r\n", a.ChapterCutRule.ToArray());
            else
                txbChapterCutRule.Text = null;

            cbIgnalLineEnable.Checked = a.IgnalLineEnable;
            cbIgnalLineRegxMode.Checked = a.IgnalLineRegxModeEnable;
            if (a.IgnalLines != null && a.IgnalLines.Count > 0)
                txbIgnalLines.Text = string.Join("\r\n", a.IgnalLines.ToArray());
            else
                txbIgnalLines.Text = null;

            cbWhiteSpace.Checked = a.WhiteSpaceEnable;
            cbLine.Checked = a.AccidentLineEnable;
        }

        private void Analizer_FromUI()
        {
            this.currentTA = new TextAnalizer();

            // 章节拆分规则
            currentTA.ChapterCutEnable = cbChapterCutEnable.Checked;
            if (currentTA.ChapterCutEnable == true)
            {
                currentTA.ChapterCutRule = new List<string>();
                currentTA.ChapterCutRule.AddRange(txbChapterCutRule.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries));
                if (currentTA.ChapterCutRule.Count == 0)
                {
                    this.mWriteInfo("章节拆分规则开启后，必须定义之。", InfoType.Warning);
                    return;
                }
            }

            // 行清理
            currentTA.AccidentLineEnable = cbLine.Checked;

            // 空格清理
            currentTA.WhiteSpaceEnable = cbWhiteSpace.Checked;

            // 无视行规则
            currentTA.IgnalLineEnable = cbIgnalLineEnable.Checked;
            currentTA.IgnalLineRegxModeEnable = cbIgnalLineRegxMode.Checked;
            if (currentTA.IgnalLineEnable == true)
            {
                currentTA.IgnalLines = new List<string>();
                currentTA.IgnalLines.AddRange(txbIgnalLines.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries));
                if (currentTA.IgnalLines.Count == 0)
                {
                    this.mWriteInfo("无视行规则开启后，必须定义之。", InfoType.Warning);
                    return;
                }
            }

            // 剪切板获取正文
            if (!Clipboard.ContainsText())
            {
                this.mWriteInfo("请将待分析文本复制到剪切板中。", InfoType.Warning);
                return;
            }
            currentTA.PlainText = Clipboard.GetText().Trim();

            currentTA.Chapters.Clear(); 
        }

        #region 规则选择
        internal enum RuleType
        {
            黑道风云,
            城北黑帮,
            三十八军在朝鲜,
            北斗推理剧场,
            狼群
        }

        internal void FillRuleByType(RuleType type)
        {
            switch (type)
            {
                case RuleType.黑道风云:
                    {
                        #region 规则
                        cbChapterCutEnable.Checked = true;
                        txbChapterCutRule.Text = @"^\s*[一二三四五六七八九十百千]+、.+$";
                        cbIgnalLineEnable.Checked = true;
                        txbIgnalLines.Text =
@"黑道风云二十年 第三部 黑社会前传
第三部 黑社会前传
第三部分 黑社会前传
第四部、黑社会
第四部分、黑社会
第四部 黑社会
第四部黑社会
★本书由我不知道论坛（bbs.wbzd.net）“once918”制作★
【TXT论坛（www.txtbbs.com），欢迎您来TXTBBS推荐好书！】";
                        cbLine.Checked = true;
                        cbWhiteSpace.Checked = true;
                        #endregion
                        break;
                    }
                case RuleType.城北黑帮:
                    {
                        #region 规则
                        cbChapterCutEnable.Checked = true;
                        txbChapterCutRule.Text = @"^[一二三四五六七八九十百千序]+ .+$";
                        cbIgnalLineEnable.Checked = true;
                        cbIgnalLineRegxMode.Checked = true;
                        txbIgnalLines.Text ="<城北黑帮正文.+\">";
                        cbLine.Checked = true;
                        cbWhiteSpace.Checked = true;
                        #endregion
                        break;
                    }
                case RuleType.三十八军在朝鲜:
                    {
                        #region 规则
                        cbChapterCutEnable.Checked = true;
                        txbChapterCutRule.Text = @"^(第[一二三四五六七八九十百千]+章 .+)|作者简介|前 言$";
                        cbIgnalLineEnable.Checked = false;
                        cbIgnalLineRegxMode.Checked = false;
                        txbIgnalLines.Text = "";
                        cbLine.Checked = true;
                        cbWhiteSpace.Checked = true;
                        #endregion
                        break;
                    }
                case RuleType.北斗推理剧场:
                    {
                        #region 规则
                        cbChapterCutEnable.Checked = true;
                        txbChapterCutRule.Text = 
@"细丫岛杀人事件 .+篇( .+章 .+)|" +
@"黑色星期五杀人事件 (.+篇\(.+\)|.+章|尾声)|" +
@"人面蛾传说杀人事件 .+篇\(.+\)|" +
@"蜡王山庄杀人事件 .+章 .+|" +
@"梦游者怪谈杀人事件 (.+章.+|尾声)|" +
@"爱缘公寓杀人事件 .+章 .+|" +
@"北斗星空 第.辑.+|" +
@"北斗外卷 (声明及简介|.+章 .+)|" +
@"北斗外卷之二 (简介|.+章 .+)";
                        cbIgnalLineEnable.Checked = true;
                        cbIgnalLineRegxMode.Checked = false;
                        txbIgnalLines.Text =
@"原案：华梦阳
原案：天丛云剑
原案：天丛
原案：轩弦
原案轩弦";
                        cbLine.Checked = true;
                        cbWhiteSpace.Checked = true;
                        #endregion
                        break;
                    }
                case RuleType.狼群:
                    {
                        #region 规则
                        cbChapterCutEnable.Checked = true;
                        txbChapterCutRule.Text = @"^(第[一二三四五六七八九十百千]+章 .+)$";
                        cbIgnalLineEnable.Checked = false;
                        cbIgnalLineRegxMode.Checked = false;
                        txbIgnalLines.Text = "";
                        cbLine.Checked = true;
                        cbWhiteSpace.Checked = true;
                        #endregion
                        break;
                    }
            }
        }
        #endregion
    }
}
